package game;

import interactables.Button;
import interactables.MenuTab;
import interactables.Tab;

import java.awt.BorderLayout;
import java.awt.Canvas;
import java.awt.Dimension;
import java.awt.event.WindowEvent;
import java.util.ArrayList;

import javax.swing.JFrame;

public class Game extends Canvas implements Runnable {

	private static final long serialVersionUID = 7249888523170536156L;

	public static final int BASE_LENGTH = 640;
	public static final int SCALE = 2;
	public static final int WIDTH = BASE_LENGTH / SCALE;
	public static final int HEIGHT = WIDTH / 12 * 9;
	public static final String NAME = "Game";
	public static Game game;

	public boolean debug = false;

	public JFrame frame;
	public boolean running = false;
	public int tickCount = 0;

	public InputHandler input;
	public Tab currTab;

	private ArrayList<Tab> tabs = new ArrayList<Tab>();

	private long lastPressProcessed = 0;

	public Game() {

		setMinimumSize(new Dimension(WIDTH * SCALE, HEIGHT * SCALE));
		setMaximumSize(new Dimension(WIDTH * SCALE, HEIGHT * SCALE));
		setPreferredSize(new Dimension(WIDTH * SCALE, HEIGHT * SCALE));

		frame = new JFrame(NAME);

		frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		frame.setLayout(new BorderLayout());

		frame.add(this, BorderLayout.CENTER);
		frame.pack();

		frame.setResizable(false);
		frame.setLocationRelativeTo(null);
		frame.setVisible(true);

	}

	public void init() {

		System.out.println("Game Start");
		game = this;

		input = new InputHandler(this);

		currTab = new MenuTab(input, game, "Menu", 0);

	}

	public synchronized void start() {

		running = true;
		new Thread(this).start();

	}

	public synchronized void stop() {

		running = false;

	}

	public void run() {

		long lastTime = System.nanoTime();
		double nsPerTick = 1000000000D / 60D;

		int ticks = 0;
		int frames = 0;
		int checkCount = 0;

		long lastTimer = System.currentTimeMillis();
		double delta = 0;

		init();

		while (running) {
			long now = System.nanoTime();
			delta += (now - lastTime) / nsPerTick;
			lastTime = now;
			boolean shouldRender = false; // Don't render unless this gets
											// changed
			boolean checkCommands = false; // Don't check commands unless things
											// change

			while (delta >= 1) {
				ticks++;
				tick();
				delta -= 1;
				shouldRender = true; // Render now, because something has
										// updated.
				checkCommands = true; // Command checking
			}

			if (shouldRender) {
				frames++;
				update();
			}

			if (checkCommands) {
				checkCount++;
				cCheck();
			}

			if (System.currentTimeMillis() - lastTimer >= 1000) {
				lastTimer += 1000;
				if (debug) {
					frame.setTitle(ticks + " ticks, " + frames + " frames");
					// Display TPS and FPS as Title
					for (Tab t : tabs) {
						System.out.println(t);
					}
				}
				frames = 0;
				ticks = 0;
			}
		}

	}

	public void tick() {

		tickCount++;

	}

	public void update() {
		if (input.mouse.isHeld()) {
			for (Button b : currTab.getButtons()) {
				b.runCheck(input.mouse.mousePosX(), input.mouse.mousePosY());
				b.render();
			}
		} else {
			for (Button b : currTab.getButtons()) {
				b.unToggle();
				b.render();
			}
		}
	}

	public void cCheck() {

		if (input.ctrl.isPressed()) {
			if (input.s.isPressed()) {
				if (System.currentTimeMillis() - lastPressProcessed > 500) {
					lastPressProcessed = System.currentTimeMillis();
					save();
				}
			}
			if (input.w.isPressed()) {
				close();
			}
			if (input.t.isPressed()) {
				if (System.currentTimeMillis() - lastPressProcessed > 500) {
					lastPressProcessed = System.currentTimeMillis();
					// TODO tabList();
				}
			}
			if (input.d.isPressed()) {
				if (System.currentTimeMillis() - lastPressProcessed > 500) {
					lastPressProcessed = System.currentTimeMillis();
					debugToggle();
				}

			}

		}

	}

	public static void main(String[] args) {

		new Game().start();

	}

	public void updateTabList(Tab t) {

		tabs.add(t);

	}

	public void save() {

	}

	public void close() {

		frame.dispatchEvent(new WindowEvent(frame, WindowEvent.WINDOW_CLOSING));

	}

	public void changeTab(Tab tab) {

		currTab = tab;

	}

	public void debugToggle() {

		System.out.println("DEBUG TOGGLED");
		debug = !debug;
		frame.setTitle(NAME);

	}

}
